﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using log4net;
using AutoFacUtils;
using CashFlow.Db.DAL;
using CashFlow.Db.Entity;
using CashFlow.Web.Service;
using CashFlow.Web.Common;
using CashFlow.Web.Def;
using CashFlow.Web.Filters;

namespace CashFlow.Web.Areas.SystemManage.Controllers
{
    [RootUserFilter]
    public class FeeController : Controller
    {
        private static readonly ILog _logger = LogManager.GetLogger(typeof(FeeController));
        private IUserService GetUserService() { return AutoFacHelper.Get<IUserService>(); }
        private IOrderService GetOrderService() { return AutoFacHelper.Get<IOrderService>(); }
        private IShopService GetShopService() { return AutoFacHelper.Get<IShopService>(); }
        private IShopUserService GetShopUserService() { return AutoFacHelper.Get<IShopUserService>(); }

        public ActionResult Index()
        {
            string date = MyCommonTool.GetOrderDate();
            var orderService = GetOrderService();
            var orders = orderService.QueryAllOrders(date);
            if (orders.Count == 0)
            {
                return View();
            }

            var userService = GetUserService();
            var ui = userService.GetLoginUser();
            var users = userService.QueryAll()
                .Where(x => x.Id != MyConfig.MTCPUserId)
                .ToList();
            var shopService = GetShopService();
            var shops = shopService.QueryAll();
            var shopUserService = GetShopUserService();
            var shopUsers = shopUserService.QueryAll();
            var ls = new List<FeeEntity>();

            #region 计算各种服务费用
            foreach (var item in users)
            {
                var feeItemData = new FeeEntity();
                feeItemData.UserId = item.Id;
                feeItemData.Date = date;
                ls.Add(feeItemData);

                var childUserIds = GetShopAllChildUserIds(item, users, shopUsers);
                var orders2 = orders.Where(x => childUserIds.Contains(x.BuyerUserId)).ToList();
                decimal percent = 0M;
                if (item.ShopManagerLevelPercent == 0)
                {
                    percent = ShopManagerLevelTool.GetShopManagerLevelPercent(orders2.Count);
                }
                else
                {
                    percent = item.ShopManagerLevelPercent;
                }

                #region 计算订单利润
                {
                    var order = orders.Where(x => x.BuyerUserId == item.Id).FirstOrDefault();
                    if (order != null && order.Id > 0)
                    {
                        feeItemData.OrderProfitFee = order.Amount * Consts.OrderPrefitPercent;
                    }
                }
                #endregion

                #region 计算店长管理费
                {
                    decimal sum = 0M;
                    var ls2 = users.Where(x => x.ReferenceInvitationCode == item.InvitationCode).ToList();
                    foreach (var item2 in ls2)
                    {
                        var childUserIds2 = GetShopAllChildUserIds(item2, users, shopUsers);
                        var orders3 = orders.Where(x => childUserIds2.Contains(x.BuyerUserId)).ToList();
                        decimal percent2 = 0M;
                        if (item2.ShopManagerLevelPercent == 0)
                        {
                            percent2 = ShopManagerLevelTool.GetShopManagerLevelPercent(orders3.Count);
                        }
                        else
                        {
                            percent2 = item2.ShopManagerLevelPercent;
                        }
                        if (percent > percent2)
                        {
                            var sum2 = orders3.Sum(x => x.Amount) * (percent - percent2);
                            sum += sum2;
                        }
                    }
                    feeItemData.ShopManagerManageFee = sum;
                }
                #endregion

                #region 计算分红
                {
                    int n = shops.Where(x => x.ShopManagerUserId == item.Id).Count();
                    if (n > 0)
                    {
                        var sum = orders2.Sum(x => x.Amount);
                        feeItemData.BoundFee = sum * Consts.BonusPercent;
                    }
                }
                #endregion

                #region 计算寄售服务费
                {
                    var sum = orders2.Sum(x => x.Amount);
                    var percent2 = Consts.ShopManagerMaxPercent + Consts.ConsignSalePercent - percent;
                    feeItemData.ConsignmentSaleFee = percent2 * sum;
                }
                #endregion
            }
            #endregion

            #region 更新到数据库
            using (var db = SqlSugarHelper.GetDb())
            {
                try
                {
                    db.BeginTran();

                    db.Deleteable<FeeEntity>(x => x.Date == date).ExecuteCommand();
                    db.Insertable<FeeEntity>(ls).ExecuteCommand();

                    db.CommitTran();
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                    db.RollbackTran();
                }
            }
            #endregion

            users.Clear();
            orders.Clear();
            shops.Clear();
            shopUsers.Clear();

            return View();
        }

        private IList<UserInfoEntity> GetAllChildUsers(UserInfoEntity userInfo
            , IList<UserInfoEntity> users)
        {
            var ls = new List<UserInfoEntity>();
            ls.Add(userInfo);

            var queue = new Queue<string>();
            queue.Enqueue(userInfo.InvitationCode);
            while (queue.Count > 0)
            {
                string code = queue.Dequeue();
                var ls2 = users.Where(x => x.ReferenceInvitationCode == code).ToList();
                foreach (var item2 in ls2)
                {
                    ls.Add(item2);
                    queue.Enqueue(item2.InvitationCode);
                }
            }

            return ls;
        }

        private IList<int> GetAllChildUserIds(UserInfoEntity userInfo
            , IList<UserInfoEntity> users)
        {
            var ls = GetAllChildUsers(userInfo, users).Select(x => x.Id).ToList();
            return ls;
        }

        private IList<UserInfoEntity> GetShopAllChildUsers(
            UserInfoEntity userInfo
            , IList<UserInfoEntity> users
            , IList<ShopUserEntity> shopUsers)
        {
            var ls = new List<UserInfoEntity>();
            ls.Add(userInfo);

            var shopUserIds = shopUsers.Select(x => x.UserId).ToList();
            var queue = new Queue<string>();
            queue.Enqueue(userInfo.InvitationCode);
            while (queue.Count > 0)
            {
                string code = queue.Dequeue();
                var ls2 = users.Where(x => x.ReferenceInvitationCode == code).ToList();
                foreach (var item2 in ls2)
                {
                    if (shopUserIds.Contains(item2.Id))
                    {
                        ls.Add(item2);
                        queue.Enqueue(item2.InvitationCode);
                    }
                }
            }

            return ls;
        }

        private IList<int> GetShopAllChildUserIds(
            UserInfoEntity userInfo
            , IList<UserInfoEntity> users
            , IList<ShopUserEntity> shopUsers)
        {
            var ls = GetShopAllChildUsers(userInfo, users, shopUsers)
                        .Select(x => x.Id)
                        .ToList();
            return ls;
        }
    }
}